﻿using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

//先在Nuget上搜索Microsoft.AspNet.SignalR安装

namespace ExpressManagement.Areas.BackSys.Hubs
{

    /// <summary>
    /// 定义集线器
    /// </summary>
    public class ChatHub : Hub
    {
        //用户集
        private readonly static Dictionary<int, string> _userId_connections = new Dictionary<int, string>();
        private readonly static Dictionary<string, int> _connections_userId = new Dictionary<string, int>();
        private readonly static HashSet<string> _group = new HashSet<string>();
        private readonly string systemid = "system";
        private readonly string systemname = "system";
        public async Task init()
        {
            await Task.CompletedTask;
        }

        //用户登陆后记录
        public async Task UserLogin(string userId, string groupName)
        {
            var connId = GetConnectionId();
            int id = Convert.ToInt32(userId);
            if (!_userId_connections.ContainsKey(id))
            {
                _userId_connections.Add(id, connId);
                _connections_userId.Add(connId, id);
                switch (groupName)
                {
                    case "用户":
                        await SendSysToOne(connId, string.Format("被分配到组群{0}", Resource.CustomerGroup));
                        await AddToGroup(Resource.CustomerGroup);
                        break;
                    default:
                        await SendSysToOne(connId, string.Format("被分配到组群{0}", Resource.CompanyGroup));
                        await AddToGroup(Resource.CompanyGroup);
                        break;
                }

            }
            else
            {
                //ConnectionId会随着每次登陆而改变
                _userId_connections[id] = connId;
                _connections_userId[connId] = id;
                await AddToGroup(groupName);
            }
        }



        #region 发送消息
        /// <summary>
        /// 以个人名义向所有客户端发送消息
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendToAll(string message)
        {
            //string cid = GetConnectionId();
            await Clients.All.SendAsync("ReceiveMessage", message);
        }

        /// <summary>
        /// 以系统名义向所有客户端发送消息
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendSysToAll(string message) => await Clients.All.SendAsync("ReceiveMessage", message);


        /// <summary>
        /// 发送消息给指定用户(个人)
        /// </summary>
        /// <param name="id"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendToOne(string id, string message)
        {
            //string cid = GetConnectionId();
            //await Clients.Client(id).ReceiveMessage(new(cid, _connections[cid], message));
            if (!_connections_userId.ContainsKey(id)) await Task.CompletedTask;
            else
                await Clients.Client(id).SendAsync("ReceiveMessage", message);
        }

        /// <summary>
        /// 发送消息给指定用户(个人)
        /// </summary>
        /// <param name="id"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendToOneByUserId(int userId, string message)
        {
            //string cid = GetConnectionId();
            //await Clients.Client(id).ReceiveMessage(new(cid, _connections[cid], message));
            if (!_userId_connections.ContainsKey(userId)) await Task.CompletedTask;
            else
            {
                await Clients.Client(_userId_connections[userId]).SendAsync("ReceiveMessage", message);

            }

        }

        /// <summary>
        /// 发送消息给指定用户(系统)F
        /// </summary>
        /// <param name="id"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendSysToOne(string id, string message)
        {
            if (!_connections_userId.ContainsKey(id)) await Task.CompletedTask;
            else
                await Clients.Client(id).SendAsync("ReceiveMessage", message);


        }



        public async Task SendSysToOneByUserId(int userId, string message)
        {
            if (!_userId_connections.ContainsKey(userId)) await Task.CompletedTask;
            else
            {
                await Clients.Client(_userId_connections[userId]).SendAsync("ReceiveMessage", message);
            }

        }




        /// <summary>
        /// 发送群组消息(个人)
        /// </summary>
        /// <param name="group"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendToGroup(string group, string message)
        {
            //string cid = GetConnectionId();
            if (!_group.Contains(group)) await Task.CompletedTask;
            else
                await Clients.Group(group).SendAsync("ReceiveMessage", message);
        }


        /// <summary>
        /// 发送群组消息(系统)
        /// </summary>
        /// <param name="group"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendSysToGroup(string group, string message)
        {
            if (!_group.Contains(group)) await Task.CompletedTask;
            else
                await Clients.Group(group).SendAsync("ReceiveMessage", message);

        }


        #endregion

        #region SiganalR用户
        private string GetConnectionId()
        {
            return Context.ConnectionId;
        }


        #endregion

        #region SignalR群组
        /// <summary>
        /// 主动加入群组
        /// </summary>
        /// <param name="group"></param>
        /// <returns></returns>
        public async Task AddToGroup(string group)
        {
            if (!_group.Contains(group)) _group.Add(group);
            string cid = GetConnectionId();
            await Groups.AddToGroupAsync(cid, group);
            await SendSysToGroup(group, $@"欢迎{cid}加入");
        }

        /// <summary>
        /// 被动加入群组
        /// </summary>
        /// <param name="group"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task AddToGrouped(string group, string id)
        {
            if (!_group.Contains(group)) _group.Add(group);
            string cid = GetConnectionId();
            await Groups.AddToGroupAsync(id, group);
            await SendSysToGroup(group, $@"欢迎{cid}加入");
        }
        #endregion

        #region 临时用户
        /// <summary>
        /// 添加到在线用户集
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task AddUser(int userId)
        {
            string cid = GetConnectionId();
            if (!_connections_userId.ContainsKey(cid))
            {
                await Task.Run(() => _connections_userId.Add(cid, userId));
                await SendSysToAll("relst");
            }
        }

        /// <summary>
        /// 获取在线用户
        /// </summary>
        /// <returns></returns>
        public object GetUser()
        {
            string cid = GetConnectionId();
            return _connections_userId.Where(t => !t.Key.Equals(cid));
        }

        #endregion
        #region 重写连接断开钩子
        /// <summary>
        /// 重写链接钩子
        /// </summary>
        /// <returns></returns>
        public override async Task OnConnectedAsync()
        {
            await base.OnConnectedAsync();
        }


        /// <summary>
        /// 重写断开连接时钩子 非async
        /// </summary>
        /// <param name="stopCalled"></param>
        /// <returns></returns>
        public override Task OnDisconnectedAsync(Exception? e)
        {
            var cid = GetConnectionId();
            if (_connections_userId.ContainsKey(cid))
            {
                _userId_connections.Remove(_connections_userId[cid]);
                _connections_userId.Remove(cid);

            }
            return base.OnDisconnectedAsync(e);
        }

        ///// <summary>
        ///// 重写连接时钩子 非async
        ///// </summary>
        ///// <returns></returns>
        //public override Task OnConnectedAsync()
        //{
        //    //return SendSysToOne(GetConnectionId(), String.Format("欢迎你登录{0}", GetConnectionId()));
        //    return base.OnConnectedAsync(e);  
        //}



        ///// <summary>
        ///// 重写断开链接钩子
        ///// </summary>
        ///// <param name="exception"></param>
        ///// <returns></returns>
        //public async Task OnDisconnectedAsync(Exception exception)
        //{
        //    string cid = GetConnectionId();
        //    if (_connections_userId.ContainsKey(cid))
        //    {
        //        _userId_connections.Remove(_connections_userId[cid]);   
        //        _connections_userId.Remove(cid);

        //    }
        //    await base.OnDisconnected(exception==null);
        //}
        #endregion



    }
}